import {useIdentityProvider, type IdentityActor} from './useSIWPIdentity';
import type {SignRequest} from '../types';

export const useActorIdentity = () => {
  const {identityActor} = useIdentityProvider();
  const actor = identityActor as IdentityActor;

  async function getProfileByName(name: string) {
    return (await actor.user_profile_get(name))[0] || null;
  }

  async function isUserExist(name: string) {
    return (await actor.is_username_registered(name))[0];
  }

  async function signTransaction(
    transaction: SignRequest,
    auth_result: string,
  ) {
    return await actor.sign_transaction_via_authentication(
      transaction,
      auth_result,
    );
  }

  async function solanaSignTx(tx: string) {
    const data = await actor.schnorr_sign(tx);
    if ('Ok' in data) {
      return data.Ok.signature_hex;
    } else {
      throw new Error(data.Err);
    }
  }

  async function checkSessionId(code: string) {
    return await actor.check_session_id(code);
  }

  async function checkSessionIdViaUsername(code: string) {
    return await actor.check_session_via_username(code);
  }

  async function startAuthenticationUsername(username: string) {
    return await actor.siwp_prepare_login_username(username);
  }

  async function finishAuthenticationUsername(signResult: string) {
    return await actor.finish_authentication_username(signResult);
  }

  async function startRegisterUsername(
    registName: string,
    passkeyTitle: string,
    serverSig: {
      server_sig: string;
      timestamp: string;
    },
    displayName: string,
  ) {
    return await actor.start_register_username(
      registName,
      passkeyTitle,
      serverSig,
      displayName,
    );
  }

  async function finishRegisterUsername(registrationResult: string) {
    return await actor.finish_register_username(registrationResult);
  }

  async function startDeletePasskey(username: string, passkeyTitle: string) {
    return await actor.start_delete_passkey(username, passkeyTitle);
  }

  async function finishDeletePasskey(deleteResult: string) {
    return await actor.finish_delete_passkey(deleteResult);
  }

  async function startBindingVerificationCode(
    bindId: string,
    validCode: string,
  ) {
    return await actor.start_binding_verification_code(bindId, validCode);
  }

  async function finishBindingVerificationCode(bindResult: string) {
    return await actor.finish_binding_verification_code(bindResult);
  }

  async function startChangeDisplayName(username: string) {
    return await actor.start_change_displayname(username);
  }

  async function finishChangeDisplayName(auth: string, display_name: string) {
    return await actor.finish_change_displayname(auth, display_name);
  }

  async function deletePasskeyViaSession(passkey_name: string) {
    return await actor.delete_passkey_via_principal(passkey_name);
  }

  async function signTransactionViaSession(transaction: SignRequest) {
    return await actor.sign_transaction_via_passkey(transaction);
  }

  async function updateDisplaynameViaSession(display_name: string) {
    return await actor.change_displayname_via_principal(display_name);
  }

  async function greet() {
    return await actor.greet();
  }

  async function signPrincipal() {
    const data = await actor.sign_principal();

    if ('Ok' in data) {
      return {message: data.Ok[0], signature: data.Ok[1]};
    } else {
      throw new Error(data.Err);
    }
  }

  async function convertSolanaAddress(username: string) {
    const data = await actor.solana_address(username);

    if ('Ok' in data) {
      return data.Ok;
    } else {
      throw new Error(data.Err);
    }
  }

  return {
    getProfileByName,
    isUserExist,
    signTransaction,
    solanaSignTx,
    checkSessionId,
    checkSessionIdViaUsername,
    startAuthenticationUsername,
    finishAuthenticationUsername,
    startRegisterUsername,
    finishRegisterUsername,
    startDeletePasskey,
    finishDeletePasskey,
    startBindingVerificationCode,
    finishBindingVerificationCode,
    startChangeDisplayName,
    finishChangeDisplayName,
    deletePasskeyViaSession,
    signTransactionViaSession,
    updateDisplaynameViaSession,
    greet,
    signPrincipal,
    convertSolanaAddress,
  };
};
